﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;

using System.Data;

namespace ETRoboConTrackingSystemServer
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "ETRoboConRaceMgmt" in code, svc and config file together.
    public class ETRoboConRaceMgmt : IETRoboConRaceMgmt
    {
        #region IETRoboConRaceMgmt Members

        public bool GetContestInfo(out ContestInfo[] infos)
        {
            infos = null;
            using (ETRCGoVADBEntities dc = new ETRCGoVADBEntities())
            {
                infos = (from contest in dc.ContestSet
                         select new ContestInfo { ContestId = contest.ContestId, Name = contest.Name }).ToArray();
            }

            return (infos != null);
        }

        public bool GetAreaInfo(int contestid, out AreaInfo[] infos)
        {
            infos = null;
            using (ETRCGoVADBEntities dc = new ETRCGoVADBEntities())
            {
                infos = (from area in dc.AreaSet
                         where area.Contest_ContestId == contestid
                         select new AreaInfo { AreaId = area.AreaId, Name = area.Name }).ToArray();
            }
            return (infos != null);
        }

        public bool GetGameInfo(int contestId, out GameInfo[] infos)
        {
            infos = null;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                infos = (from game in context.GameSet
                         where game.Contest_ContestId == contestId
                         orderby game.Name
                         select new GameInfo { Name = game.Name, GameId = game.GameId, GameSpecId = game.GameSpec_GameSpecId,AreaName=game.AreaSet.Name }).ToArray();
            }
            return (infos != null);
        }

        public bool GetBonusSpecInfo(int gameId, CourseName course, out BonusSpecInfo[] infos)
        {
            infos = null;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var query = (from g in context.GameSet
                             where g.GameId == gameId
                             select g);
                var game = query.First();
                if (game != null)
                {
                    string courseName = course.ToString();
                    infos = (from bs in context.BonusSpecSet
                             where bs.GameCourseSpecSet.CourseName.CompareTo(courseName) == 0 && bs.GameCourseSpecSet.GameSpec_GameSpecId == game.GameSpec_GameSpecId
                             orderby bs.ClearOrder
                             select new BonusSpecInfo
                             {
                                 BonusSpecId = bs.BonusSpecId,
                                 Name = bs.Name,
                                 ShortName = bs.ShortName,
                                 Specification = bs.Specification,
                                 Point = bs.Point,
                                 ClearOrder = bs.ClearOrder
                             }).ToArray();
                }
            }
            return (infos != null);
        }

        public bool GetCurrentRound(int gameId, out int roundNo, out int roundId)
        {
            roundId = -1;
            roundNo = -1;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var query = (from r in context.RaceSet
                             where r.TurnSet.RoundSet.Game_GameId == gameId
                             select r);
                if (query.Count() > 0)
                {
                    RaceSet current = query.First();
                    if (current != null)
                    {
                        roundId = current.TurnSet.Round_RoundId;
                        roundNo = current.TurnSet.RoundSet.RoundNo;
                    }
                }
            }
            return (roundId != -1);
        }

        public bool GetTurnInfo(int currentRoundId, out int turnNo, out int turnId, out int inCourseRunnerId, out int outCourseRunnerId)
        {
            turnNo = -1;
            turnId = -1;
            inCourseRunnerId = -1;
            outCourseRunnerId = -1;

            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var query = (from r in context.RaceSet
                             where r.TurnSet.Round_RoundId == currentRoundId
                             orderby r.TurnOrder ascending
                             select r);
                if (query.Count() > 0)
                {
                    RaceSet current = query.First();

                    turnNo = current.TurnSet.TurnNo;
                    turnId = current.Turn_TurnId;
                    EntryTeamSet icr = current.TurnSet.EntryTeamSet;
                    EntryTeamSet ocr = current.TurnSet.EntryTeamSet1;

                    if (icr != null)
                    {
                        var iTR = (from tr in context.TurnRunnerSet
                                   where tr.EntryTeam_EntryTeamId == icr.EntryTeamId && tr.Turn_TurnId == current.Turn_TurnId
                                   select tr);
                        if (iTR.Count() > 0)
                        {
                            TurnRunnerSet tr = iTR.First();
                            if (tr.Status.CompareTo(RunnerStatus.READY.ToString()) == 0)
                            {
                                if (current.TurnSet.InCourseEntryTeam_EntryTeamId != null)
                                {
                                    inCourseRunnerId = current.TurnSet.InCourseEntryTeam_EntryTeamId.Value;
                                }
                            }
                        }
                    }
                    if (ocr != null)
                    {
                        var oTR = (from tr in context.TurnRunnerSet
                                   where tr.EntryTeam_EntryTeamId == ocr.EntryTeamId && tr.Turn_TurnId == current.Turn_TurnId
                                   select tr);
                        if (oTR.Count() > 0)
                        {
                            var tr = oTR.First();
                            if (tr.Status.CompareTo(RunnerStatus.READY.ToString()) == 0)
                            {
                                if (current.TurnSet.OutCourseEntryTeam_EntryTeamId != null)
                                {
                                    outCourseRunnerId = current.TurnSet.OutCourseEntryTeam_EntryTeamId.Value;
                                }
                            }
                        }
                    }
                    return true;
                }
            }
            return false;
        }

        public bool StartRound(int gameId, int roundNo, out int roundId)
        {
            roundId = -1;

            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var rps = (from rp in context.RunnerPointSet
                           where rp.TurnRunnerSet.EntryTeamSet.Game_GameId == gameId && rp.TurnRunnerSet.TurnSet.RoundSet.RoundNo == roundNo
                           select rp);
                //                int count = rps.Count();
                if (rps.Count() > 0)
                {
                    foreach (var rp in rps)
                    {
                        context.RunnerPointSet.DeleteObject(rp);
                    }
                    context.SaveChanges();
                }
                //                context.RunnerPoint.DeleteAllOnSubmit(rps);
                //                context.SubmitChanges();

                var trs = (from tr in context.TurnRunnerSet
                           where tr.EntryTeamSet.Game_GameId == gameId && tr.TurnSet.RoundSet.RoundNo == roundNo
                           select tr);
                //                count = trs.Count();
                if (trs.Count() > 0)
                {
                    foreach (var tr in trs)
                    {
                        context.TurnRunnerSet.DeleteObject(tr);
                    }
                    context.SaveChanges();
                }
                //                context.TurnRunner.DeleteAllOnSubmit(trs);
                //              context.SubmitChanges();

                var query = (from r in context.RoundSet
                             where r.Game_GameId == gameId && r.RoundNo == roundNo
                             select r);
                if (query.Count() == 0)
                {
                    return false;
                }

                var current = query.First();
                var races = (from r in context.RaceSet
                             where r.TurnSet.Round_RoundId == current.RoundId
                             select r);
                if (races.Count() > 0)
                {
                    foreach (var r in races)
                    {
                        context.RaceSet.DeleteObject(r);
                    }
                    context.SaveChanges();
                }
                //                context.Race.DeleteAllOnSubmit(races);
                //context.SubmitChanges();
            }
            using(var context = new ETRCGoVADBEntities()){
                var query = (from r in context.RoundSet
                             where r.Game_GameId == gameId && r.RoundNo == roundNo
                             select r);
                var current = query.First();
                var turns = (from t in context.TurnSet
                             where t.Round_RoundId == current.RoundId
                             orderby t.TurnNo ascending
                             select t);

                int order = 0;
                var dbTurns = new List<TurnSet>();
                foreach (var turn in turns)
                {
                    dbTurns.Add(turn);
                }
                foreach (var turn in dbTurns)
                {
                    var race = new RaceSet
                    {
                        TurnSet = turn,
                        TurnOrder = order++
                    };
                    //                    race.RaceID = Guid.NewGuid();
                    // race.TurnSet = turn;
                    // race.TurnOrder = order++;
                    context.AddToRaceSet(race);
                    context.SaveChanges();
                    //                    context.Race.InsertOnSubmit(race);
                    //                  context.SubmitChanges();

                    if (turn.InCourseEntryTeam_EntryTeamId != null)
                    {
                        TurnRunnerSet itr = new TurnRunnerSet
                        {
                            TurnSet = turn,
                            RaceSet = race,
                            EntryTeamSet = turn.EntryTeamSet,
                            Status = RunnerStatus.READY.ToString()
                        };
                        //   itr.TurnRunnerID = Guid.NewGuid();
                   //     itr.TurnSet = turn;
                     //   itr.RaceSet = race;
                       // itr.EntryTeamSet = turn.EntryTeamSet;
                        string courseName = CourseName.IN.ToString();
                        itr.GameCourseSpecSet = (from gcs in context.GameCourseSpecSet
                                                 where gcs.GameSpec_GameSpecId == current.GameSet.GameSpec_GameSpecId &&
                                                 gcs.CourseName.CompareTo(courseName) == 0
                                                 select gcs).First();
                 //       itr.Status = RunnerStatus.READY.ToString();
                        context.TurnRunnerSet.AddObject(itr);
                        context.SaveChanges();
                        //                        context.TurnRunner.InsertOnSubmit(itr);
                        //                      context.SubmitChanges();
                    }
                    if (turn.OutCourseEntryTeam_EntryTeamId != null)
                    {
                        TurnRunnerSet otr = new TurnRunnerSet();
                        //                        otr.TurnRunnerID = Guid.NewGuid();
                        otr.TurnSet = turn;
                        otr.RaceSet = race;
                        otr.EntryTeamSet = turn.EntryTeamSet1;
                        string courseName = CourseName.OUT.ToString();
                        otr.GameCourseSpecSet = (from gcs in context.GameCourseSpecSet
                                                 where gcs.GameSpec_GameSpecId == current.GameSet.GameSpec_GameSpecId
                                                 && gcs.CourseName.CompareTo(courseName) == 0
                                                 select gcs).First();
                        otr.Status = RunnerStatus.READY.ToString();
                        context.AddToTurnRunnerSet(otr);
                        context.SaveChanges();
                        //                        context.TurnRunner.InsertOnSubmit(otr);
                        //                      context.SubmitChanges();
                    }
                }

                roundId = current.RoundId;

            }

            return (roundId != -1);
        }

        public bool ContinueRound(int gameId, out int roundId)
        {
            roundId = -1;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var query = (from r in context.RaceSet
                             where r.TurnSet.RoundSet.Game_GameId == gameId
                             select r);
                if (query.Count() > 0)
                {
                    var current = query.First();
                    roundId = current.TurnSet.Round_RoundId;
                    return true;
                }
            }
            return false;
        }

        public bool EndRound(int currentRoundId)
        {
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var query = (from r in context.RaceSet
                             where r.TurnSet.Round_RoundId == currentRoundId
                             select r);
                if (query.Count() > 0)
                {
                    foreach (var race in query)
                    {
                        TurnRunnerSet[] trs = (race.TurnRunnerSet).ToArray();
                        foreach (var tr in trs)
                        {
                            tr.RaceSet = null;
                        }
                        context.RaceSet.DeleteObject(race);
                    }
                    //                   context.Race.DeleteAllOnSubmit(query);
                    //                 context.SubmitChanges();
                    context.SaveChanges();

                    return true;
                }
            }
            return false;
        }

        public bool RollbackTurn(int currentRoundId)
        {
            bool result = false;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var rounds = from r in context.RoundSet
                             where r.RoundId == currentRoundId
                             select r;
                if (rounds.Count() > 0)
                {
                    var round = rounds.First();
                    TurnSet lastTurn = null;
                    int raceOrder = -1;
                    var turns = from t in round.TurnSet
                                orderby t.TurnNo
                                select t;
                    foreach (var turn in turns)
                    {
                        if (turn.RaceSet.Count > 0)
                        {
                            raceOrder = turn.RaceSet.First().TurnOrder - 1;
                            break;
                        }
                        lastTurn = turn;
                    }
                    if (lastTurn != null && raceOrder >= 0)
                    {
                        var race = new RaceSet() { TurnOrder = raceOrder };
                        race.TurnSet = lastTurn;
                        context.SaveChanges();
                        foreach (var tr in lastTurn.TurnRunnerSet)
                        {
                            tr.RaceSet = race;
                            tr.Status = "READY";
                        }
                        context.SaveChanges();
                        //                        context.SubmitChanges();
                        return true;
                    }
                }
            }
            return result;
        }

        public bool NotifyRaceResult(int turnId, int currentRunnerId, RunnerStatus status, int runTime, int[] bonusClearResult, out int point)
        {
            point = -1;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var turns = (from t in context.TurnSet
                             where t.TurnId == turnId
                             select t);
                if (turns.Count() > 0)
                {
                    var turn = turns.First();
                    EntryTeamSet eTeam = null;
                    CourseName cource = CourseName.IN;
                    if (turn.EntryTeamSet != null)
                    {
                        if (turn.EntryTeamSet.EntryTeamId == currentRunnerId)
                        {
                            eTeam = turn.EntryTeamSet;
                            cource = CourseName.IN;
                        }
                    }
                    if (turn.EntryTeamSet1 != null)
                    {
                        if (turn.EntryTeamSet1.EntryTeamId == currentRunnerId)
                        {
                            eTeam = turn.EntryTeamSet1;
                            cource = CourseName.OUT;
                        }
                    }


                    if (eTeam != null)
                    {
                        var turnRunners = from tr in context.TurnRunnerSet
                                          where tr.EntryTeam_EntryTeamId == eTeam.EntryTeamId
                                          && tr.Turn_TurnId == turn.TurnId
                                          select tr;
                        if (turnRunners.Count() > 0)
                        {
                            var turnRunner = turnRunners.First();
                            turnRunner.Status = status.ToString();
                            turnRunner.RunTime = runTime;
                            turnRunner.ResultPoint = point = CalculateRunnerPoint(context, turn.RoundSet.GameSet, turnRunner, cource, runTime, bonusClearResult);
                            turnRunner.RaceSet = null;
                        }
                        context.SaveChanges();
                        //                        context.SubmitChanges();
                        UpdateRaceOrder(context, turn);
                        return true;
                    }
                }
            }
            return false;
        }

        public bool NotifyObstructed(int turnId, int currentRunnerId, bool retryNow)
        {
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var query = (from r in context.RaceSet
                             where r.Turn_TurnId == turnId
                             select r);
                if (query.Count() > 0)
                {
                    var race = query.First();
                    var trs = (from tr in race.TurnRunnerSet
                               where tr.EntryTeam_EntryTeamId==currentRunnerId
                               select tr);
                    if (trs.Count() >= 1)
                    {
                        var tr = trs.First();
                        tr.Status = RunnerStatus.OBSTRUCTED.ToString();
                        tr.RunTime = 1200;
                        tr.ResultPoint = 1200;
                        tr.RaceSet = null;
                        if (!retryNow)
                        {
                            var races = (from r in context.RaceSet
                                         where r.TurnSet.Round_RoundId == race.TurnSet.Round_RoundId
                                         orderby r.TurnOrder descending
                                         select r);
                            race.TurnOrder = races.First().TurnOrder + 1;
                        }
                        context.SaveChanges();
//                        context.SubmitChanges();
                        return true;
                    }
                }
            }
            return false;
        }

        public bool GetTeamInfoByEntryTeam(int entryTeamId, out TeamInfo teamInfo)
        {
            teamInfo = null;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var query = (from te in context.EntryTeamSet
                             where te.EntryTeamId == entryTeamId
                             select te);
                if (query.Count() > 0)
                {
                    var dbTeamInfo = query.First();
                    teamInfo = new TeamInfo
                             {
                                 TeamId = dbTeamInfo.Team_TeamId,
                                 EntryTeamId = dbTeamInfo.EntryTeamId,
                                 Name = dbTeamInfo.TeamSet.Name,
                                 Bib = dbTeamInfo.Bib,
                                 Exhibition = dbTeamInfo.Exibition
                     //            Id = dbTeamInfo.TeamSet.RegId.ToString()
                             };
                }
            }
            return (teamInfo != null);
        }

        #endregion

        private int CalculateRunnerPoint(ETRCGoVADBEntities context, GameSet game, TurnRunnerSet turnRunner, CourseName course, int time, int[] bonusResults)
        {
            string courseName = course.ToString();
            var bonusSpecs = (from bs in context.BonusSpecSet
                              where game.GameSpec_GameSpecId == bs.GameCourseSpecSet.GameSpec_GameSpecId
                              && bs.GameCourseSpecSet.CourseName.CompareTo(courseName) == 0
                              //                              where game.GameSpecSet.Equals(bs.GameCourseSpecSet.GameSpecSet) && bs.GameCourseSpecSet.CourseName.CompareTo(course.ToString()) == 0
                              select bs);
            int point = 0;
            if (bonusResults != null)
            {
                foreach (var bonusResult in bonusResults)
                {
                    foreach (var bonusSpec in bonusSpecs)
                    {
                        if (bonusSpec.BonusSpecId == bonusResult)
                        {
                            var rp = new RunnerPointSet();
                            rp.Acquired = true;
                            rp.BonusSpecSet = bonusSpec;
                            rp.TurnRunnerSet = turnRunner;
                            point += bonusSpec.Point;
                            break;
                        }
                    }
                }
            }
            //            context.SubmitChanges();
            context.SaveChanges();


            return time - (10 * point);
        }


        private void UpdateRaceOrder(ETRCGoVADBEntities context, TurnSet turn)
        {
            bool turnFinished = true;
            foreach (var tr in turn.TurnRunnerSet)
            {
                if (tr.Status.CompareTo(RunnerStatus.READY.ToString()) == 0)
                {
                    turnFinished = false;
                    break;
                }
            }
            if (turnFinished)
            {
                var races = from r in context.RaceSet
                            where r.Turn_TurnId == turn.TurnId
                            select r;
                foreach (var r in races)
                {
                    context.DeleteObject(r);
                }
//                foreach (var r in turn.RaceSet)
  //              {
    //                context.RaceSet.DeleteObject(r);
      //          }
                context.SaveChanges();
//                context.Race.DeleteAllOnSubmit(turn.Race);
  //              context.SubmitChanges();
            }
        }

        #region IETRoboConRaceMgmt Members


        public bool GetEntryTeamInfo(int gameId, out TeamInfo[] temaInfos)
        {
            temaInfos = null;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                temaInfos = (from te in context.EntryTeamSet
                             where te.Game_GameId == gameId
                             orderby te.Bib
                             select new TeamInfo
                             {
                                 TeamId = te.Team_TeamId,
                                 EntryTeamId = te.EntryTeamId,
                                 Name = te.TeamSet.Name,
                                 Bib = te.Bib,
                                 //      Id = te.TeamSet.RegId.ToString()
                                 RegId = te.TeamSet.RegId
                             }).ToArray();
            }
            return (temaInfos != null);
        }

        public bool GetGameSpecInfo(out GameSpecInfo[] gameSpecInfos)
        {
            gameSpecInfos = null;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                gameSpecInfos = (from gs in context.GameSpecSet
                                 select new GameSpecInfo
                                 {
                                     GameSpecId = gs.GameSpecId,
                                     Name = gs.Name,
                                     Memo = gs.Memo
                                 }).ToArray();

            }
            if (gameSpecInfos.Length > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool GetRaceOrder(int gameId, int roundNo, out TurnInfo[] turnInfos)
        {
            turnInfos = null;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
#if false
                turnInfos = (from turn in context.TurnSet
                             where turn.RoundSet.RoundNo == roundNo && turn.RoundSet.Game_GameId == gameId
                             orderby turn.TurnNo
                             select new TurnInfo
                             {
                                 TurnId = turn.TurnId,
                                 No = turn.TurnNo,
                                 InCourseRunnerId = turn.EntryTeamSet.EntryTeamId,
                                 OutCourseRunnerId = turn.EntryTeamSet1.EntryTeamId
                             }
                            ).ToArray();
#endif
                var tis = new List<TurnInfo>();
                var turns = from t in context.TurnSet
                            where t.RoundSet.RoundNo == roundNo && t.RoundSet.Game_GameId == gameId
                            orderby t.TurnNo
                            select t;
                foreach (var turn in turns)
                {
                    var ti = new TurnInfo() { TurnId = turn.TurnId, No = turn.TurnNo, InCourseRunnerId = -1, OutCourseRunnerId = -1 };
                    if (turn.EntryTeamSet != null)
                    {
                        ti.InCourseRunnerId = turn.EntryTeamSet.EntryTeamId;
                    }
                    if (turn.EntryTeamSet1 != null)
                    {
                        ti.OutCourseRunnerId = turn.EntryTeamSet1.EntryTeamId;
                    }
                    tis.Add(ti);
                }
                turnInfos = tis.ToArray();
            }
            return (turnInfos != null);
        }

        public bool GetTeamRaceResult(int turnID, int entryTeamId, out RunnerStatus status, out int? runTime, out int? runPoint, out string[] bonusResults)
        {
            bool result = false;
            status = RunnerStatus.UNKNOWN;
            runTime = null;
            runPoint = null;
            bonusResults = null;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var query = (from turnRunner in context.TurnRunnerSet
                             where turnRunner.Turn_TurnId==turnID && turnRunner.EntryTeam_EntryTeamId==entryTeamId
                             select turnRunner);
                if (query.Count() == 1)
                {
                    var turnRunner = query.First();
                    if (turnRunner.Status.CompareTo("READY") == 0)
                    {
                        status = RunnerStatus.READY;
                    }
                    else if (turnRunner.Status.CompareTo("COMPLETED") == 0)
                    {
                        status = RunnerStatus.COMPLETED;
                    }
                    else if (turnRunner.Status.CompareTo("RETIRED") == 0)
                    {
                        status = RunnerStatus.RETIRED;
                    }
                    else if (turnRunner.Status.CompareTo("OBSTRUCTED") == 0)
                    {
                        status = RunnerStatus.OBSTRUCTED;

                    }
                    else if (turnRunner.Status.CompareTo("DECLINED") == 0)
                    {
                        status = RunnerStatus.DECLINED;
                    }
                    if (status == RunnerStatus.COMPLETED || status == RunnerStatus.RETIRED || status == RunnerStatus.OBSTRUCTED)
                    {
                        runPoint = turnRunner.ResultPoint;
                        runTime = turnRunner.RunTime;
                        if (status != RunnerStatus.OBSTRUCTED)
                        {
                            bonusResults = (from br in context.RunnerPointSet
                                            where br.TurnRunner_TurnRunnerId==turnRunner.TurnRunnerId
                                            select br.BonusSpecSet.ShortName).ToArray();
                        }
                    }
                    result = true;
                }
            }
            return result;
        }

        public bool UpdateTeamRaceResult(int turnID, int entryTeamId, RunnerStatus status, int? runTime, string[] bonusResults, out int? runPoint)
        {
            bool result = false;
            runPoint = null;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var query = (from tr in context.TurnRunnerSet
                             where tr.Turn_TurnId==turnID && tr.EntryTeam_EntryTeamId==entryTeamId
                             select tr);
                if (query.Count() == 1)
                {
                    var turnRunner = query.First();
                    var runnerPoints = (from rp in context.RunnerPointSet
                                        where rp.TurnRunner_TurnRunnerId==turnRunner.TurnRunnerId
                                        select rp);
                    foreach (var rp in runnerPoints)
                    {
                        context.RunnerPointSet.DeleteObject(rp);
                    }
                    context.SaveChanges();
//                    context.RunnerPoint.DeleteAllOnSubmit(runnerPoints);
  //                  context.SubmitChanges();

                    turnRunner.Status = status.ToString();
                    if (status == RunnerStatus.READY  || status == RunnerStatus.UNKNOWN)
                    {
                        turnRunner.RunTime = null;
                        turnRunner.ResultPoint = null;
                    }
                    if (status == RunnerStatus.COMPLETED || status == RunnerStatus.RETIRED)
                    {
                        turnRunner.RunTime = runTime;
                        if (status == RunnerStatus.RETIRED)
                        {
                            turnRunner.RunTime = 1200;
                        }
                        CourseName cn = CourseName.IN;
                        if (turnRunner.TurnSet.InCourseEntryTeam_EntryTeamId != turnRunner.EntryTeam_EntryTeamId)
                        {
                            cn = CourseName.OUT;
                        }
                        string courseName = cn.ToString();
                        var bonusSpecs = (from bs in context.BonusSpecSet
                                          where
                                          bs.GameCourseSpecSet.GameSpec_GameSpecId==turnRunner.TurnSet.RoundSet.GameSet.GameSpec_GameSpecId
                                          && bs.GameCourseSpecSet.CourseName.CompareTo(courseName) == 0
                                          select bs);
                        List<int> brGuids = new List<int>();
                        foreach (string br in bonusResults)
                        {
                            foreach (var bs in bonusSpecs)
                            {
                                if (bs.ShortName.CompareTo(br) == 0)
                                {
                                    //                                RunnerPoint rp = new RunnerPoint();
                                    //                                rp.BonusSpec = bs;
                                    //                                rp.TurnRunner = turnRunner;
                                    brGuids.Add(bs.BonusSpecId);
                                    break;
                                }
                            }
                        }
                        turnRunner.ResultPoint = CalculateRunnerPoint(context, turnRunner.TurnSet.RoundSet.GameSet, turnRunner, cn, (int)runTime, brGuids.ToArray());
                        runPoint = turnRunner.ResultPoint;
                    }
                    if (status == RunnerStatus.OBSTRUCTED || status == RunnerStatus.DECLINED)
                    {
                        turnRunner.RunTime = 1200;
                        turnRunner.ResultPoint = 1200;
                        runPoint = turnRunner.ResultPoint;
                    }
                    context.SaveChanges();
                  //  context.SubmitChanges();
                    result = true;
                }
            }
            return result;
        }

        public bool UpdateEntryTeamResultInfo(int entryTeamId, int? modelPoint, int? rank)
        {
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var entryTeam = from et in context.EntryTeamSet
                                where et.EntryTeamId==entryTeamId
                                select et;
                if (entryTeam.Count() > 0)
                {
                    var target = entryTeam.First();
                    target.ModelTotalPoint = modelPoint;
                    target.Rank = rank;
                    context.SaveChanges();
//                    context.SubmitChanges();
                    return true;
                }
            }
            return false;
        }

        public bool GetEntryTeamResultInfos(int gameId, out EntryTeamResultInfo[] results,bool doCalc)
        {
            results = null;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var games = from g in context.GameSet
                            where g.GameId == gameId
                            select g;
                if (games.Count() > 0)
                {
                    var game = games.First();
                    var entryTeams = from et in context.EntryTeamSet
                                     where et.Game_GameId == game.GameId && (et.Exibition == null || et.Exibition == false)
                                     select et;
                    foreach (var entryTeam in entryTeams)
                    {
                        int runPoint = 0;
                        foreach (var turnRunner in entryTeam.TurnRunnerSet)
                        {
                            if (turnRunner.ResultPoint != null)
                            {
                                runPoint += (int)turnRunner.ResultPoint;
                            }
                        }
                        entryTeam.RaceTotalPoint = runPoint;
                    }
                    context.SaveChanges();
//                    context.SubmitChanges();

                    if (doCalc)
                    {
                        var nmp = new Dictionary<int, double>();
                        var nrp = new Dictionary<int, double>();
                        CaliculateRaceOrder(gameId, out nrp, out nmp);
                    }

                    var etResults = from et in context.EntryTeamSet
                                    where et.Game_GameId == game.GameId &&
                                        (et.Exibition == null || et.Exibition == false)// &&
//                                        (et.ModelTotalPoint != null)
                                    orderby et.Bib
                                    select new EntryTeamResultInfo
                                    {
                                        TeamRegId = et.TeamSet.RegId,
                                        TeamId = et.Team_TeamId,
                                        EntryTeamId = et.EntryTeamId,
                                        Bib = et.Bib,
                                        TeamName = et.TeamSet.Name,
                                        ModelPoint = et.ModelTotalPoint,
                                        TotalRunPoint = et.RaceTotalPoint,
                                        TotalPoint = et.TotalPoint,
                                        Rank = et.Rank
                                    };
                    results = etResults.ToArray();
                    return true;
                }
            }
            return false;
        }

        private void CaliculateRaceOrder(int gameId,out Dictionary<int,double> normalizedRunPoints,out Dictionary<int,double> normalizedModelPoints)
        {

            using (var db = new ETRCGoVADBEntities())
            {
                var entryTeamSet = from et in db.EntryTeamSet
                                   where et.Game_GameId == gameId
                                   select et;
                var tmpETs = new List<EntryTeamSet>();
                foreach (var tet in entryTeamSet)
                {
                    tet.TotalPoint = null;
                    tet.Rank = null;
                }
                db.SaveChanges();

                var entryTeams = from et in db.EntryTeamSet
                                 where et.Game_GameId == gameId
                                 && (et.Exibition == null || et.Exibition == false)
                                 && et.ModelTotalPoint != null && et.RaceTotalPoint != null
                                 select et;


                int effectiveEntryTeamNo = entryTeams.Count();

                var etModelPoints = new Dictionary<int, double>();
                var etRunPoints = new Dictionary<int, double>();
                var etTotalPoints = new Dictionary<int, double?>();

                double mpMax = 0.0;
                double mpMin = 1000.0;
                double rpMax = -1000.0;
                double rpMin = 240.0;

                foreach (var entryTeam in entryTeams)
                {
                    double mp = (double)entryTeam.ModelTotalPoint;
                    double rp = ((double)entryTeam.RaceTotalPoint) / 10;
                    if (mp < mpMin)
                    {
                        mpMin = mp;
                    }
                    if (mp > mpMax)
                    {
                        mpMax = mp;
                    }
                    if (rp < rpMin)
                    {
                        rpMin = rp;
                    }
                    if (rp > rpMax)
                    {
                        rpMax = rp;
                    }
                }

                double mpDelta = mpMax-mpMin;
                double rpDelta=rpMax-rpMin;
                foreach (var entryTeam in entryTeams)
                {
                    double mp = (double)entryTeam.ModelTotalPoint;
                    double rp = ((double)entryTeam.RaceTotalPoint) / 10;
                    double nmp = 0.5;
                    if (mpDelta != 0)
                    {
                        nmp = (mp - mpMin) / mpDelta;
                    }
                    double nrp = 0.0;
                    if (rpDelta != 0.0)
                    {
                        nrp = 1 - (rp - rpMin) / rpDelta;
                    }
                    double tp = 0.0;
                    if (nmp != 0 && nrp != 0)
                    {
                        tp = 2 * nmp * nrp / (nmp + nrp);
                    }
                    etModelPoints.Add(entryTeam.EntryTeamId, nmp);
                    etRunPoints.Add(entryTeam.EntryTeamId, nrp);
                    etTotalPoints.Add(entryTeam.EntryTeamId, tp);
                }

                foreach (var etId in etTotalPoints.Keys)
                {
                    var ets = from et in db.EntryTeamSet where et.EntryTeamId == etId select et;
                    if (ets.Count() > 0)
                    {
                        var et = ets.First();
                        et.TotalPoint = etTotalPoints[etId];
                        db.SaveChanges();
                    }
                }
#if false
                double modelPointSum = 0.0;
                double runPointSum = 0.0;
                foreach (var entryTeam in entryTeams)
                {
                    if (runPointLimitation > entryTeam.RaceTotalPoint)
                    {
                        etModelPoints.Add(entryTeam.EntryTeamId, (double)entryTeam.ModelTotalPoint);
                        etRunPoints.Add(entryTeam.EntryTeamId, (double)entryTeam.RaceTotalPoint);
                        etTotalPoints.Add(entryTeam.EntryTeamId, null);
                        modelPointSum += (double)entryTeam.ModelTotalPoint;
                        runPointSum += (double)entryTeam.RaceTotalPoint;
                    }
                }

                if (etModelPoints.Count > 0)
                {
                    double modelPointAve = modelPointSum / etModelPoints.Count;
                    double modelDeltaSum = 0.0;
                    double runPointAve = runPointSum/etRunPoints.Count;
                    double runDeltaSum = 0.0;
                    foreach (var id in etModelPoints.Keys)
                    {
                        double delta = etModelPoints[id]-modelPointAve;
                        modelDeltaSum += delta * delta;
                        delta = etRunPoints[id] - runPointAve;
                        runDeltaSum += delta * delta;
                    }
                    double modelPointStDev = System.Math.Sqrt(modelDeltaSum / etModelPoints.Count);
                    double runPointStDev = System.Math.Sqrt(runDeltaSum / etRunPoints.Count);
                    var totalPoints = new Dictionary<int, double>();
                    foreach (var id in etTotalPoints.Keys)
                    {
                        etModelPoints[id] = 50 + 10 * (etModelPoints[id] - modelPointAve) / modelPointStDev;
                        etRunPoints[id] = 50 - 10 * (etRunPoints[id] - runPointAve) / runPointStDev;
                        totalPoints[id] = (etModelPoints[id] + etRunPoints[id]) / 2;
                    }

                    foreach (var id in etTotalPoints.Keys)
                    {
                        var ets = from et in db.EntryTeamSet where et.EntryTeamId == id select et;
                        if (ets.Count() > 0)
                        {
                            var et = ets.First();
                            et.TotalPoint = totalPoints[id];
                        }

                    }
                    db.SaveChanges();
                }
#endif
#if false
                DataTable rpTable = new DataTable("RunPoints");
                DataColumn rpIdColumn = new DataColumn("Id", typeof(System.Int32));
                DataColumn rpPColumn = new DataColumn("Point", typeof(System.Double));
                DataColumn rStdColumn = new DataColumn("StDev", typeof(System.Double), "StDev(Point)");
                rpTable.Columns.Add(rpIdColumn);
                rpTable.Columns.Add(rpPColumn);
                rpTable.Columns.Add(rStdColumn);

                foreach (var key in etRunPoints.Keys)
                {
                    var newRow = rpTable.NewRow();
                    newRow["Id"] = key;
                    newRow["Point"] = etRunPoints[key];
                    rpTable.Rows.Add(newRow);
                }

                DataTable mpTable = new DataTable("ModelPoints");
                DataColumn mpIdColumn = new DataColumn("Id", typeof(System.Int32));
                DataColumn mpPColumn = new DataColumn("Point", typeof(System.Double));
                DataColumn mpStDColumn = new DataColumn("StDev", typeof(System.Double), "StDev(Point)");

                mpTable.Columns.Add(mpIdColumn);
                mpTable.Columns.Add(mpPColumn);
                mpTable.Columns.Add(mpStDColumn);

                foreach (var key in etModelPoints.Keys)
                {
                    var newRow = mpTable.NewRow();
                    newRow["Id"] = key;
                    newRow["Point"] = etModelPoints[key];
                    mpTable.Rows.Add(newRow);
                }

                for (int i = 0; i < mpTable.Rows.Count; i++)
                {
                    var mpRow = mpTable.Rows[i];
                    int id = int.Parse(mpRow["Id"].ToString());
                    double mpStDev = double.Parse(mpRow["StDev"].ToString());
                    double rpStDev = 0;
                    for (int j=0;j<rpTable.Rows.Count;j++)
                    {
                        int rpId = int.Parse(rpTable.Rows[j]["Id"].ToString());
                        if (rpId == id)
                        {
                            rpStDev = double.Parse(rpTable.Rows[j]["StDev"].ToString());
                            break;
                        }
                    }
                    etTotalPoints[id] = mpStDev + rpStDev;
                }

                foreach (var id in etTotalPoints.Keys)
                {
                    var ets = from et in db.EntryTeamSet
                              where et.Game_GameId == gameId && et.EntryTeamId == id
                              select et;
                    if (ets.Count() > 0)
                    {
                        var entryTeam = ets.First();
                        entryTeam.TotalPoint = etTotalPoints[id];
                    }
                }
                db.SaveChanges();
#endif


                var pEntryTeams = from et in db.EntryTeamSet
                                  where et.Game_GameId == gameId && et.TotalPoint != null && et.ModelTotalPoint != null
                                  orderby et.TotalPoint descending
                                  select et;
                int rank = 0;
                int rankDelta = 1;
                double currentPoint = 1000;
                foreach (var et in pEntryTeams)
                {
                    if (currentPoint > et.TotalPoint)
                    {
                        rank += rankDelta;
                        currentPoint = et.TotalPoint.Value;
                        rankDelta = 1;
                    }
                    else
                    {
                        rankDelta++;
                    }
                    et.Rank = rank;
                }
                db.SaveChanges();
                var nEntryTeams = from et in db.EntryTeamSet
                                  where et.Game_GameId == gameId && et.TotalPoint == null
                                  && (et.Exibition == null || et.Exibition == false)
                                  select et;
                foreach (var et in nEntryTeams)
                {
//                    et.Rank = effectiveEntryTeamNo;
                }
                db.SaveChanges();

                normalizedModelPoints = etModelPoints;
                normalizedRunPoints = etRunPoints;
            }
        }

        private void CalicurateRaceOrderOld(int gameId)
        {

            using (var db = new ETRCGoVADBEntities())
            {
                var entryTeams = from et in db.EntryTeamSet
                                 where et.Game_GameId == gameId
                                 && (et.Exibition == null || et.Exibition != false)
                                 && et.ModelTotalPoint!=null && et.RaceTotalPoint!=null
                                 select et;
                int effectiveEntryTeamNo = entryTeams.Count();

                double modelMin = 10000;
                double modelMax = 0;
                var etModelPoints = new Dictionary<int, double>();
                double runMin = 1300;
                double runMax = -1300;
                var etRunPoints = new Dictionary<int, double>();
                foreach (var entryTeam in entryTeams)
                {
                    etModelPoints.Add(entryTeam.EntryTeamId, (double)entryTeam.ModelTotalPoint);
                    if (modelMin > (double)entryTeam.ModelTotalPoint)
                    {
                        modelMin = (double)entryTeam.ModelTotalPoint;
                    }
                    if (modelMax < (double)entryTeam.ModelTotalPoint)
                    {
                        modelMax = (double)entryTeam.ModelTotalPoint;
                    }

                    etRunPoints.Add(entryTeam.EntryTeamId, (double)entryTeam.RaceTotalPoint);
                    if (runMin > (double)entryTeam.RaceTotalPoint)
                    {
                        runMin = (double)entryTeam.RaceTotalPoint;
                    }
                    if (runMax < (double)entryTeam.RaceTotalPoint)
                    {
                        runMax = (double)entryTeam.RaceTotalPoint;
                    }
                }

                if (modelMin < modelMax)
                {
                    double modelDelta = modelMax - modelMin;
                    foreach (var etId in etModelPoints.Keys)
                    {
                        etModelPoints[etId] = 100 * (etModelPoints[etId] - modelMin) / modelDelta;
                    }
                }
                if (runMin < runMax)
                {
                    double runDelta = runMax - runMin;
                    foreach (var etId in etRunPoints.Keys)
                    {
                        etRunPoints[etId] = 100 * (1 - ((etRunPoints[etId] - runMin) / runDelta));
                    }
                }

                var etTotalPoints = new Dictionary<int, double?>();
                foreach (var etId in etModelPoints.Keys)
                {
                    if (etModelPoints[etId] == 0)
                    {
                        if (etRunPoints[etId] == 0)
                        {
                            etTotalPoints.Add(etId, null);
                        }
                        else
                        {
                            etTotalPoints.Add(etId, 0);
                        }
                    }
                    else
                    {
                        if (etRunPoints[etId] == 0)
                        {
                            etTotalPoints.Add(etId, 0);
                        }
                        else
                        {
                            double totalPoint =
                                (etRunPoints[etId] * etModelPoints[etId])
                                / (etRunPoints[etId] + etModelPoints[etId]);
                            etTotalPoints.Add(etId, totalPoint);
                        }
                    }
                }

                foreach (var entryTeam in entryTeams)
                {
                    if (etTotalPoints.ContainsKey(entryTeam.EntryTeamId))
                    {
                        entryTeam.TotalPoint = etTotalPoints[entryTeam.EntryTeamId];
                    }
                    else
                    {
                        entryTeam.TotalPoint = null;
                    }
                }
                db.SaveChanges();

                var pEntryTeams = from et in db.EntryTeamSet
                                  where et.Game_GameId == gameId && et.TotalPoint != null
                                  orderby et.TotalPoint descending
                                  select et;
                int rank = 0;
                int rankDelta = 1;
                double currentPoint = 1000;
                foreach (var et in pEntryTeams)
                {
                    if (currentPoint > et.TotalPoint)
                    {
                        rank += rankDelta;
                        currentPoint = et.TotalPoint.Value;
                        rankDelta = 1;
                    }
                    else
                    {
                        rankDelta++;
                    }
                    et.Rank = rank;
                }
                db.SaveChanges();
                var nEntryTeams = from et in db.EntryTeamSet
                                  where et.Game_GameId == gameId && et.TotalPoint == null
                                  && (et.Exibition == null || et.Exibition == false)
                                  select et;
                foreach (var et in nEntryTeams)
                {
                    et.Rank = effectiveEntryTeamNo;
                }
                db.SaveChanges();

            }
        }

        public bool RegistContest(string name, string memo, int year, out int contestId)
        {
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var contests = from c in context.ContestSet
                               where c.Name.CompareTo(name) == 0 && c.Year == year
                               select c;
                if (contests.Count() == 0)
                {
                    var contest = new ContestSet { Name = name, Year = year, Memo = memo };
                    context.AddToContestSet(contest);
                    context.SaveChanges();
//                    context.Contest.InsertOnSubmit(contest);
  //                  context.SubmitChanges();
                    contestId = contest.ContestId;
                    return true;
                }
                else
                {
                    var contest = contests.First();
                    contest.Memo = memo;
                    context.SaveChanges();
//                    context.SubmitChanges();
                    contestId = contest.ContestId;

                    return false;
                }
            }
        }

        public bool RegistNewGame(int areaId, int gameSpecId, string gameName, out int gameId)
        {
            gameId = -1;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var areas = from a in context.AreaSet
                            where a.AreaId == areaId
                            select a;
                if (areas.Count() > 0)
                {
                    var area = areas.First();
                    var contest = area.ContestSet;
                    var games = from g in contest.GameSet
                                where g.Name.CompareTo(gameName) == 0 && g.Area_AreaId == area.AreaId
                                select g;
                    var gameSpecs = from gs in context.GameSpecSet
                                    where gs.GameSpecId == gameSpecId
                                    select gs;
                    if (gameSpecs.Count() > 0)
                    {
                        GameSet game = null;
                        if (games.Count() > 0)
                        {
                            game = games.First();
                            game.GameSpecSet = gameSpecs.First();
                            context.SaveChanges();
                        }
                        else
                        {
                            var gameSpec = gameSpecs.First();
                            game = new GameSet { Name = gameName };
                            game.ContestSet = contest;
                            game.GameSpecSet = gameSpec;
                            game.AreaSet = area;
                            context.AddToGameSet(game);
                        }
                        context.SaveChanges();
                        //                        context.Game.InsertOnSubmit(game);
                        //                      context.SubmitChanges();
                        gameId = game.GameId;
                        return true;
                    }
                }
            }
            return false;
        }

        public bool RegistTeam(int contestId,string areaName, string teamName, string categoryName, string Id, long regId, out int teamId)
        {
            teamId = -1;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var areas = from a in context.AreaSet
                            where a.Name.CompareTo(areaName) == 0 && a.Contest_ContestId == contestId
                            select a;
                if (areas.Count()>0){
//                    int regId = int.Parse(Id);
                    var area = areas.First();
                    var teams = from t in area.TeamSet
                                //                                where t.Name.CompareTo(teamName) == 0 && t.RegId == regId
                                where t.RegId == regId
                                select t;
                    if (teams.Count() == 0)
                    {
              //          var team = new TeamSet { Name = teamName, Id = new Guid(Id) };
                        var team = new TeamSet { Name = teamName, RegId = regId, Category=categoryName };
                        team.AreaSet = area;
                        context.AddToTeamSet(team);
                        context.SaveChanges();
                        
//                        context.SubmitChanges();
                        teamId = team.TeamId;
                    }
                    else if (teams.Count() == 1)
                    {
                        var team = teams.First();
                        team.Name = teamName;
                        team.AreaSet = area;
                        team.Category = categoryName;
                        context.SaveChanges();

                        teamId = team.TeamId;
                        
                    }
                    return true;
                }
            }
            return false;
        }

        public bool RegistEntryTeam(int gameId, int teamId, int bib, bool isExibition, out int entryTeamId)
        {
            entryTeamId = -1;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var games = from g in context.GameSet
                            where g.GameId == gameId
                            select g;
                if (games.Count() > 0)
                {
                    var game = games.First();
                    var teams = from t in context.TeamSet
                                where t.TeamId == teamId
                                select t;

                    var teamEntry = new EntryTeamSet { Bib = bib };
                    teamEntry.GameSet = game;
                    teamEntry.TeamSet = teams.First();
                    if (isExibition)
                    {
                        teamEntry.Exibition = true;
                    }
                    teamEntry.Status = "REGISTED";

                    context.AddToEntryTeamSet(teamEntry);
                    context.SaveChanges();
//                    context.SubmitChanges();
                    entryTeamId = teamEntry.EntryTeamId;
                    return true;
                }
            }
            return false;
        }

        public bool ClearGameRound(int gameId)
        {
            using (var context = new ETRCGoVADBEntities())
            {
                var games = from g in context.GameSet where g.GameId == gameId select g;
                if (games.Count() > 0)
                {
                    var game = games.First();
                    var dbRounds = new List<RoundSet>();
                    var rounds = from r in game.RoundSet select r;
                    foreach (var r in rounds)
                    {
                        dbRounds.Add(r);
                    }
                    foreach (var round in dbRounds)
                    {
                        var turns = from t in round.TurnSet select t;
                        var dbTurns = new List<TurnSet>();
                        foreach (var t in turns)
                        {
                            dbTurns.Add(t);
                        }
                        foreach (var dbTurn in dbTurns)
                        {
                            var turnRunners = from tr in dbTurn.TurnRunnerSet select tr;
                            var dbTurnRunners = new List<TurnRunnerSet>();
                            foreach (var tr in turnRunners)
                            {
                                dbTurnRunners.Add(tr);
                            }
                            foreach (var dbTurnRunner in dbTurnRunners)
                            {
                                var runnerPoints = from trp in dbTurnRunner.RunnerPointSet select trp;
                                var dbRunnerPoints = new List<RunnerPointSet>();
                                foreach (var runnerPoint in runnerPoints)
                                {
                                    dbRunnerPoints.Add(runnerPoint);
                                }
                                foreach (var dbRunerPoint in dbRunnerPoints)
                                {
                                    context.DeleteObject(dbRunerPoint);
                                }
                                context.DeleteObject(dbTurnRunner);
                            }
                            context.DeleteObject(dbTurn);
                        }
                        context.DeleteObject(round);
                        context.SaveChanges();
                    }
                    var dbEntryTeams = new List<EntryTeamSet>();
                    var entryTeams = from et in game.EntryTeamSet select et;
                    foreach (var et in entryTeams)
                    {
                        dbEntryTeams.Add(et);
                    }
                    foreach (var entryTeam in dbEntryTeams)
                    {
                        var dbTurnRunners = new List<TurnRunnerSet>();
                        var turnRunners = from tr in entryTeam.TurnRunnerSet select tr;
                        foreach (var tr in turnRunners)
                        {
                            dbTurnRunners.Add(tr);
                        }
                        foreach (var turnRunner in dbTurnRunners)
                        {
                            var dbRunnerPoints = new List<RunnerPointSet>();
                            var runnerPoints = from rp in turnRunner.RunnerPointSet select rp;
                            foreach (var rp in runnerPoints)
                            {
                                dbRunnerPoints.Add(rp);
                            }
                            foreach (var runnerPoint in dbRunnerPoints)
                            {
                                context.DeleteObject(runnerPoint);
                            }
                            context.DeleteObject(turnRunner);
                        }
                        context.DeleteObject(entryTeam);
                    }
                    context.SaveChanges();                        
                    
                    return true;
                }
            }
            return false;
        }

        public bool RegistRound(int gameId, int roundNo, out int roundId)
        {
            roundId = -1;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var games = from g in context.GameSet
                            where g.GameId == gameId
                            select g;
                if (games.Count() > 0)
                {
                    var game = games.First();
                    var rounds = from r in context.RoundSet
                                 where r.Game_GameId == gameId && r.RoundNo == roundNo
                                 select r;
                    if (rounds.Count() == 0)
                    {
                        var round = new RoundSet { RoundNo = roundNo };
                        round.GameSet = game;
                        context.AddToRoundSet(round);
                        context.SaveChanges();
                        //                    context.SubmitChanges();
                        roundId = round.RoundId;
                        return true;
                    }
                    else
                    {
                        // ラウンドが既に登録済みの場合は、Turn, TurnRunner, Race, RunnerPointを削除する。
                        // EntryTeamは削除しない。
                        var dbRound = rounds.First();
                        roundId = rounds.First().RoundId;
                        return true;
                    }
                }
            }
            return false;
        }

        public bool RegistTurn(int roundId, int inCourseRunnerId, int outCourseRunnerId, out int turnId)
        {
            turnId = -1;
            if (inCourseRunnerId == -1 && outCourseRunnerId == -1)
            {
                return false;
            }
            //            using (DataClassesDataContext context = new DataClassesDataContext())
            using (var context = new ETRCGoVADBEntities())
            {
                var rounds = from r in context.RoundSet
                             where r.RoundId == roundId
                             select r;
                if (rounds.Count() > 0)
                {
                    var round = rounds.First();
                    var turns = from t in context.TurnSet
                                where t.Round_RoundId == roundId
                                select t;
                    int no = turns.Count() + 1;
                    var turn = new TurnSet { TurnId = -1, TurnNo = no };
                    turn.RoundSet = round;
                    //                    Guid nullGuid = new Guid();
                    if (inCourseRunnerId != -1)
                    {
                        var icEntry = from ic in context.EntryTeamSet
                                      where ic.EntryTeamId == inCourseRunnerId
                                      select ic;
                        turn.EntryTeamSet = icEntry.First();
                    }
                    if (outCourseRunnerId != -1)
                    {
                        var ocEntry = from oc in context.EntryTeamSet
                                      where oc.EntryTeamId == outCourseRunnerId
                                      select oc;
                        turn.EntryTeamSet1 = ocEntry.First();
                    }

                    context.AddToTurnSet(turn);
                    context.SaveChanges();
                    //                    context.SubmitChanges();
                    turnId = turn.TurnId;

                    FixTurnRunner(round.Game_GameId);
                    return true;
                }
            }
            return false;
        }

        public bool RegistRound2AllTurnsByAuto(int gameId, int round1Id, out int round2Id)
        {
            round2Id = -1;
            //            using (DataClassesDataContext context = new DataClassesDataContext())
            using (var context = new ETRCGoVADBEntities())
            {
                var rounds = from r in context.RoundSet
                             where r.RoundId == round1Id && r.Game_GameId == gameId
                             select r;
                if (rounds.Count() > 0)
                {
                    RoundSet round = rounds.First();
                    GameSet game = round.GameSet;
                    if (round.RoundNo == 1)
                    {
                        RoundSet r2 = null;
                        var round2s = from r in context.RoundSet
                                      where r.Game_GameId == gameId && r.RoundNo == 2
                                      select r;
                        if (round2s.Count() == 0)
                        {
                            r2 = new RoundSet { RoundNo = 2 };
                            r2.GameSet = game;
                            context.AddToRoundSet(r2);
                            context.SaveChanges();
                        }
                        else
                        {
                            r2 = round2s.First();
                        }
                        var turns = from t in context.TurnSet
                                    where t.Round_RoundId == round.RoundId
                                    orderby t.TurnNo
                                    select t;
                        round2Id = r2.RoundId;
                        //                        context.SubmitChanges();
                        var dbTurns = new List<TurnSet>();
                        foreach (var turn in turns)
                        {
                            dbTurns.Add(turn);
                        }
                        foreach (var turn in dbTurns)
                        {
                            var turn2 = new TurnSet { TurnNo = turn.TurnNo };
                            turn2.RoundSet = r2;
                            turn2.EntryTeamSet = turn.EntryTeamSet1;
                            turn2.EntryTeamSet1 = turn.EntryTeamSet;
                            context.AddToTurnSet(turn2);
                            context.SaveChanges();
                            //                            context.SubmitChanges();
                        }

                        FixTurnRunner(gameId);

                        return true;
                    }
                }
            }
            return false;
        }

        public bool FixTurnRunner(int gameId)
        {
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var games = from g in context.GameSet
                            where g.GameId == gameId
                            select g;
                if (games.Count() > 0)
                {
                    var game = games.First();
                    GameCourseSpecSet igcs = null;
                    GameCourseSpecSet ogcs = null;
                    foreach (var gcs in game.GameSpecSet.GameCourseSpecSet)
                    {
                        if (gcs.CourseName.CompareTo("IN") == 0)
                        {
                            igcs = gcs;
                        }
                        if (gcs.CourseName.CompareTo("OUT") == 0)
                        {
                            ogcs = gcs;
                        }
                        if (igcs != null && ogcs != null)
                        {
                            break;
                        }
                    }
                    var turns = from t in context.TurnSet
                                where t.RoundSet.Game_GameId == game.GameId
                                select t;
                    var dbTurns = new List<TurnSet>();
                    foreach (var turn in turns)
                    {
                        dbTurns.Add(turn);
                    }
                    foreach (var turn in dbTurns)
                    {
                        if (turn.EntryTeamSet != null)
                        {
                            var itr = new TurnRunnerSet { Status = RunnerStatus.READY.ToString() };
                            itr.EntryTeamSet = turn.EntryTeamSet;
                            itr.GameCourseSpecSet = igcs;
                            itr.TurnSet = turn;
                            context.AddToTurnRunnerSet(itr);
                        }
                        if (turn.EntryTeamSet1 != null)
                        {
                            var otr = new TurnRunnerSet { Status = RunnerStatus.READY.ToString() };
                            otr.EntryTeamSet = turn.EntryTeamSet1;
                            otr.GameCourseSpecSet = ogcs;
                            otr.TurnSet = turn;
                            context.AddToTurnRunnerSet(otr);
                        }
                        context.SaveChanges();
//                        context.SubmitChanges();
                    }
                }
            }
            return false;
        }

        public bool ClearGameInfo(int gameId)
        {
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var games = from g in context.GameSet
                            where g.GameId==gameId
                            select g;
                if (games.Count() > 0)
                {
                    var game = games.First();
                    foreach (var round in game.RoundSet)
                    {
                        foreach (var turn in round.TurnSet)
                        {
                            var turnRunners = from tr in context.TurnRunnerSet
                                              where tr.Turn_TurnId == turn.TurnId
                                              select tr;
                            foreach (var tr in turnRunners)
                            {
                                context.TurnRunnerSet.DeleteObject(tr);
                            }
                            context.SaveChanges();
//                            context.TurnRunner.DeleteAllOnSubmit(turnRunners);
                            context.TurnSet.DeleteObject(turn);
                        }
//                        context.Turn.DeleteAllOnSubmit(round.Turn);
                        context.SaveChanges();
                        context.RoundSet.DeleteObject(round);
                    }
                    context.SaveChanges();
//                    context.Round.DeleteAllOnSubmit(game.Round);
                    var teams = new List<TeamSet>();
                    foreach (var entryTeam in game.EntryTeamSet)
                    {
                        teams.Add(entryTeam.TeamSet);
                        context.EntryTeamSet.DeleteObject(entryTeam);
                    }
                    context.SaveChanges();
//                    context.EntryTeam.DeleteAllOnSubmit(game.EntryTeam);
                    foreach (var team in teams)
                    {
                        context.TeamSet.DeleteObject(team);
//                        context.Team.DeleteOnSubmit(team);
                    }
                    context.GameSet.DeleteObject(game);
                }
                context.SaveChanges();
 //               context.Game.DeleteAllOnSubmit(games);
   //             context.SubmitChanges();
                return true;
            }
            return false;
        }

        public bool ClearGameSpecInfo(string gameSpecName)
        {
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var gameSpecs = from gs in context.GameSpecSet
                                where gameSpecName.CompareTo(gs.Name) == 0
                                select gs;
                if (gameSpecs.Count() > 0)
                {
                    var gameSpec = gameSpecs.First();
                    var games = from g in context.GameSet
                                where g.GameSpec_GameSpecId == gameSpec.GameSpecId
                                select g;
                    if (games.Count() == 0)
                    {
                        foreach (var gcs in gameSpec.GameCourseSpecSet)
                        {
                            foreach (var bs in gcs.BonusSpecSet)
                            {
                                context.BonusSpecSet.DeleteObject(bs);
                            }
                            context.SaveChanges();
//                            context.BonusSpec.DeleteAllOnSubmit<BonusSpec>(gameCourceSpec.BonusSpec);
                            context.GameCourseSpecSet.DeleteObject(gcs);
                        }
                        context.SaveChanges();
//                        context.GameCourceSpec.DeleteAllOnSubmit<GameCourceSpec>(gameSpec.GameCourceSpec);
                    }
                    foreach (var g in games)
                    {
                        context.GameSet.DeleteObject(g);
                    }
                    context.SaveChanges();
//                    context.GameSpec.DeleteOnSubmit(gameSpec);
  //                  context.SubmitChanges();
                    return true;
                }
            }
            return false;
        }

        public GameSpecInfo FindGameSpec(string gameSpecName)
        {
            GameSpecInfo gsInfo = null;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var gameSpecs = from gs in context.GameSpecSet
                                where gs.Name.CompareTo(gameSpecName) == 0
                                select gs;
                if (gameSpecs.Count() > 0)
                {
                    var gameSpec = gameSpecs.First();
                    gsInfo = new GameSpecInfo { GameSpecId = gameSpec.GameSpecId, Name = gameSpecName, Memo = gameSpec.Memo };
                }
            }
            return gsInfo;
        }

        public bool RegistGameSpec(string gameSpecName, string Memo, out int gameSpecId)
        {
            bool isNew = true;
            gameSpecId = -1;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var gameSpecs = from gs in context.GameSpecSet
                                where gs.Name.CompareTo(gameSpecName) == 0
                                select gs;
                if (gameSpecs.Count() > 0)
                {
                    var gameSpec = gameSpecs.First();
                    gameSpecId = gameSpec.GameSpecId;
                    gameSpec.Memo = Memo;
                    isNew = false;
                }
                else
                {
                    var gameSpec = new GameSpecSet { Name = gameSpecName, Memo = Memo };
                    context.AddToGameSpecSet(gameSpec);
                    context.SaveChanges();
                    //                    context.GameSpec.InsertOnSubmit(gameSpec);

                    var gcsIn = new GameCourseSpecSet { CourseName = CourseName.IN.ToString(), GameSpecSet = gameSpec };
                    context.GameCourseSpecSet.AddObject(gcsIn);
                    //                    context.GameCourceSpec.InsertOnSubmit(gcsIn);

                    var gcsOut = new GameCourseSpecSet { CourseName = CourseName.OUT.ToString(), GameSpecSet = gameSpec };
                    context.GameCourseSpecSet.AddObject(gcsOut);
                    //                    context.GameCourceSpec.InsertOnSubmit(gcsOut);
                }
                context.SaveChanges();
                //                context.SubmitChanges();
            }
            return isNew;
        }

        public bool ClearBonusSpecs(string gameSpecName, CourseName courseName)
        {
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var gameSpecs = from gs in context.GameSpecSet
                                where gameSpecName.CompareTo(gs.Name) == 0
                                select gs;
                if (gameSpecs.Count() > 0)
                {
                    var gameSpec = gameSpecs.First();
                    string courseNameStr = courseName.ToString();
                    var gameCourseSpecs = from gcs in gameSpec.GameCourseSpecSet
                                          where gcs.CourseName.CompareTo(courseNameStr) == 0
                                          select gcs;
                    foreach (var gcs in gameCourseSpecs)
                    {
                        foreach (var bs in gcs.BonusSpecSet)
                        {
                            context.BonusSpecSet.DeleteObject(bs);
                        }
                        context.SaveChanges();
                        context.GameCourseSpecSet.DeleteObject(gcs);
                    }
                    context.SaveChanges();
//                    if (gameCourseSpecs.Count() > 0)
  //                  {
                    //
                      //  context.BonusSpec.DeleteAllOnSubmit<BonusSpec>(gameCourseSpecs.First().BonusSpec);

                        //context.SubmitChanges();

                        return true;
                //    }

                }
            }

            return false;
        }

        public bool UpdaetGameSpecInfo(int gameSpecId, string name, string memo)
        {
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var gameSpecs = from gs in context.GameSpecSet
                                where gs.GameSpecId == gameSpecId
                                select gs;
                if (gameSpecs.Count() > 0)
                {
                    var gameSpec = gameSpecs.First();
                    gameSpec.Name = name;
                    gameSpec.Memo = memo;
                    context.SaveChanges();
//                    context.SubmitChanges();
                    return true;
                }
            }
            return false;
        }

        public bool AppendBonusSpec(int gameSpecId, CourseName courseName, string name, string shortName, string specification, int point, out int clearOrder, out int bonusSpecId)
        {
            clearOrder = -1;
            bonusSpecId = -1;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var gameSpecs = from gs in context.GameSpecSet
                                where gs.GameSpecId == gameSpecId
                                select gs;
                if (gameSpecs.Count() > 0)
                {
                    var gameSpec = gameSpecs.First();
                    string courseNameStr = courseName.ToString();
                    var gameCourceSpecs = from gcs in gameSpec.GameCourseSpecSet
                                          where gcs.CourseName.CompareTo(courseNameStr) == 0
                                          select gcs;
                    if (gameCourceSpecs.Count() > 0)
                    {
                        var gameCourceSpec = gameCourceSpecs.First();
                        var bonusSpecs = from bs in gameCourceSpec.BonusSpecSet
                                         where bs.ShortName.CompareTo(shortName) == 0
                                         select bs;
                        if (bonusSpecs.Count() == 0)
                        {
                            var bonusSpec = new BonusSpecSet { Name = name, ShortName = shortName, Specification = specification, Point = point, ClearOrder = gameCourceSpec.BonusSpecSet.Count };
                            bonusSpec.GameCourseSpecSet = gameCourceSpec;
                            context.AddToBonusSpecSet(bonusSpec);
                            context.SaveChanges();
//                            bonusSpecId = bonusSpec.BonusSpecID;
                            clearOrder = bonusSpec.ClearOrder;
                            bonusSpecId = bonusSpec.BonusSpecId;
//                            context.BonusSpec.InsertOnSubmit(bonusSpec);
  //                          context.SubmitChanges();

                            return true;
                        }
                    }
                }
            }
            return false;
        }

        public bool GetGameCourseBonusSpecInfo(int gameSpecId, CourseName courseName, out BonusSpecInfo[] infos)
        {
            infos = null;
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var gameSpecs = from gs in context.GameSpecSet
                                where gs.GameSpecId == gameSpecId
                                select gs;
                if (gameSpecs.Count() > 0)
                {
                    var gameSpec = gameSpecs.First();
                    GameCourseSpecSet gameCourceSpec = null;
                    foreach (var gcs in gameSpec.GameCourseSpecSet)
                    {
                        if (gcs.CourseName.CompareTo(courseName.ToString()) == 0)
                        {
                            gameCourceSpec = gcs;
                            break;
                        }
                    }
                    if (gameCourceSpec != null)
                    {
                        infos = (from bs in gameCourceSpec.BonusSpecSet
                                 orderby bs.ClearOrder
                                 select new BonusSpecInfo
                                 {
                                     BonusSpecId = bs.BonusSpecId,
                                     Name = bs.Name,
                                     ShortName = bs.ShortName,
                                     Specification = bs.Specification,
                                     GameCourseSpecId = bs.GameCourseSpec_GameCourseSpecId,
                                     Point = bs.Point,
                                     ClearOrder = bs.ClearOrder
                                 }).ToArray();
                        return true;
                    }
                }
            }
            return false;
        }
        
        public bool GetContestById(int contestId, out int year, out string name, out string memo)
        {
            year = -1;
            name = "";
            memo = "";
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var contests = from c in context.ContestSet
                               where c.ContestId == contestId
                               select c;
                if (contests.Count() > 0)
                {
                    var contest = contests.First();
                    year = contest.Year;
                    name = contest.Name;
                    memo = contest.Memo;
                    return true;
                }
            }
            return false;
        }

        public bool LoadGameSpec(string specName, string definition)
        {
            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var registed = from gs in context.GameSpecSet
                               where gs.Name.CompareTo(specName) == 0
                               select gs;
                TextReader textSource = new StringReader(definition);
                XmlReader reader = XmlReader.Create(textSource);
                XDocument doc = XDocument.Load(reader);
                var gameSpecs = doc.Elements("Contests").First().Elements("GameSpecs").First().Elements("GameSpec");
                if (registed.Count() == 0)
                {
                    foreach (var gameSpec in gameSpecs)
                    {
                        if (gameSpec.Attribute("Name").Value.CompareTo(specName) != 0)
                        {
                            continue;
                        }

                        Guid gsId = new Guid(gameSpec.Attribute("Id").Value);

                        var newGS = new GameSpecSet { Name = specName };
                        context.AddToGameSpecSet(newGS);
                        context.SaveChanges();
//                        context.GameSpec.InsertOnSubmit(newGS);
  //                      context.SubmitChanges();

                        foreach (var gcs in gameSpec.Elements("Courses").First().Elements("Course"))
                        {
                            Guid gcsId = new Guid(gcs.Attribute("Id").Value);
                            var newGCS = new GameCourseSpecSet { CourseName = gcs.Attribute("Name").Value, GameSpecSet = newGS };
                            context.AddToGameCourseSpecSet(newGCS);
                            context.SaveChanges();
//                            newGCS.GameSpec = newGS;
  //                          context.GameCourceSpec.InsertOnSubmit(newGCS);
    //                        context.SubmitChanges();
                            int order = 0;
                            foreach (var bs in gcs.Elements("BonusPoints").First().Elements("BonusPoint"))
                            {
                                Guid bsId = new Guid();
                                if (bs.Attribute("Id") != null)
                                {
                                    bsId = new Guid(bs.Attribute("Id").Value);
                                }
                                else
                                {
                                    bsId = Guid.NewGuid();
                                }
                                var newBS = new BonusSpecSet
                                {
                                    Name = bs.Attribute("Name").Value,
                                    ShortName = bs.Attribute("Key").Value,
                                    Point = Int32.Parse(bs.Attribute("Point").Value),
                                    ClearOrder = order++,
                                    GameCourseSpecSet = newGCS
                                };
                                var specs = bs.Elements("Specification");
                                if (specs.Count() > 0)
                                {
                                    newBS.Specification = specs.First().Value;
                                }
                                else
                                {
                                    newBS.Specification = "";
                                }

//                                newBS.GameCourceSpec = newGCS;
                                context.AddToBonusSpecSet(newBS);
                                context.SaveChanges();
//                                context.BonusSpec.InsertOnSubmit(newBS);
  //                              context.SubmitChanges();
                            }
                        }
                    }
                    return true;
                }
                else
                {
                    var registedGS = registed.First();
                    foreach (var gameSpec in gameSpecs)
                    {
                        if (gameSpec.Attribute("Name").Value.CompareTo(specName) != 0)
                        {
                            continue;
                        }
//                        Guid gsId = new Guid(gameSpec.Attribute("Id").Value);

  //                      if (gsId.CompareTo(registedGS.GameSpecID) != 0)
    //                    {
      //                      break;
        //                }

                        foreach (var gcs in gameSpec.Elements("Courses").First().Elements("Course"))
                        {
                            var registedGCSs = from rgcs in registedGS.GameCourseSpecSet
                                               where rgcs.CourseName.CompareTo(gcs.Attribute("Name").Value) == 0
                                               select rgcs;
                            if (registedGCSs.Count() > 0)
                            {
                                var registedGCS = registedGCSs.First();
                                int order = 0;
                                foreach (var bs in gcs.Elements("BonusPoints").First().Elements("BonusPoint"))
                                {
                                    var registedBSs = from rbs in registedGCS.BonusSpecSet
                                                      where rbs.ShortName.CompareTo(bs.Attribute("Key").Value) == 0
                                                      select rbs;
                                    if (registedBSs.Count() > 0)
                                    {
                                        var registedBS = registedBSs.First();
                                        registedBS.Name = bs.Attribute("Name").Value;
                                        registedBS.Point = System.Convert.ToInt32(bs.Attribute("Point").Value);
                                        registedBS.ClearOrder = order;
                                        var specs = bs.Elements("Specification");
                                        if (specs.Count() > 0)
                                        {
                                            registedBS.Specification = specs.First().Value;
                                        }
                                        else
                                        {
                                            registedBS.Specification = "";
                                        }

                                        context.SaveChanges();
//                                        context.SubmitChanges();
                                    }
                                    else
                                    {
                                        Guid bsId = new Guid();
                                        if (bs.Attribute("Id") != null)
                                        {
                                            bsId = new Guid(bs.Attribute("Id").Value);
                                        }
                                        else
                                        {
                                            bsId = Guid.NewGuid();
                                        }
                                        var newBS = new BonusSpecSet
                                        {
                                            Name = bs.Attribute("Name").Value,
                                            ShortName = bs.Attribute("Key").Value,
                                            Point = Int32.Parse(bs.Attribute("Point").Value),
                                            ClearOrder = order++,
                                            GameCourseSpecSet = registedGCS
                                        };

                                        var specs = bs.Elements("Specification");
                                        if (specs.Count() > 0)
                                        {
                                            newBS.Specification = specs.First().Value;
                                        }
                                        else
                                        {
                                            newBS.Specification = "";
                                        }

                                    //    newBS.GameCourceSpec = registedGCS;
                                        context.AddToBonusSpecSet(newBS);
                                        context.SaveChanges();
//                                        context.BonusSpec.InsertOnSubmit(newBS);
  //                                      context.SubmitChanges();
                                    }
                                    order++;
                                }
                            }
                        }
                    }
                    return true;
                }
            }

            return false;
        }

        public bool LoadTeamInfo(string contestName, string definition)
        {
            XmlReader reader = XmlReader.Create(new StringReader(definition));
            XDocument xdoc = XDocument.Load(reader);

            var contests = from c in xdoc.Elements("Contests").First().Elements("Contest")
                           where contestName.CompareTo(c.Attribute("Name").Value) == 0
                           select c;

            if (contests.Count() > 0)
            {
                var targetContest = contests.First();
                using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
                {
                    var rcs = from rc in context.ContestSet
                              where rc.Name.CompareTo(contestName) == 0
                              select rc;
                    ContestSet contest = null;
                    if (rcs.Count() > 0)
                    {
                        contest = rcs.First();
                    }
                    else
                    {
                        contest = new ContestSet
                        {
//                            ContestID = new Guid(targetContest.Attribute("Id").Value),
                            Name = targetContest.Attribute("Name").Value,
                            Year = System.Convert.ToInt32(targetContest.Attribute("Year").Value)
                        };
                        context.AddToContestSet(contest);
                        context.SaveChanges();
//                        context.Contest.InsertOnSubmit(contest);
  //                      context.SubmitChanges();
                    }
                    if (contest != null)
                    {
                        var registedAreas = new Dictionary<string, AreaSet>();
                        var areas = from a in targetContest.Elements("Areas").First().Elements("Area")
                    //                where areaName.CompareTo(a.Attribute("Name").Value) == 0
                                    select a;
                        foreach (var area in areas)
                        {
                            var regAreas = from a in contest.AreaSet
                                                where a.Name.CompareTo(area.Attribute("Name").Value) == 0
                                                select a;
                            if (regAreas.Count() > 0)
                            {
                                var regArea = regAreas.First();
                                registedAreas.Add(regArea.Name, regArea);
                            }
                            else
                            {
                                var newArea = new AreaSet
                                {
                                    Name = area.Attribute("Name").Value,
                                    ContestSet = contest
                                };
                                context.AddToAreaSet(newArea);
                                context.SaveChanges();
                                registedAreas.Add(newArea.Name, newArea);
                            }
                            var targetArea = area;
                            var currentArea = registedAreas[area.Attribute("Name").Value];
                            foreach (var teamInfo in targetArea.Elements("Teams").First().Elements("Team"))
                            {
                                var rts = from rt in currentArea.TeamSet
                                          where rt.RegId.CompareTo(teamInfo.Attribute("Id").Value) == 0
                                          select rt;
                                TeamSet team = null;
                                if (rts.Count() > 0)
                                {
                                    team = rts.First();
                                    team.Name = teamInfo.Attribute("Name").Value;
                               //     team.Location = teamInfo.Attribute("Location").Value;
                                    team.AreaSet = currentArea;
                                    team.Organization = teamInfo.Attribute("BelongTo").Value;
                                    team.Category = teamInfo.Attribute("Category").Value;
                                    team.Memo = teamInfo.Attribute("Division").Value;
                                    if (teamInfo.Attribute("Exhibition") != null)
                                    {
                                        team.Memo += ";Exhibition=" + teamInfo.Attribute("Exhibition").Value;
                                    }
                                    context.SaveChanges();
//                                    context.SubmitChanges();
                                }
                                else
                                {
                                    team = new TeamSet
                                    {
                                        //      Id = new Guid(teamInfo.Attribute("Id").Value),
                                        RegId = int.Parse(teamInfo.Attribute("Id").Value),
                                        Name = teamInfo.Attribute("Name").Value,
                                        //                                        Location = teamInfo.Attribute("Location").Value,
                                        AreaSet = currentArea,
                                        Organization = teamInfo.Attribute("BelongTo").Value,
                                        Category = teamInfo.Attribute("Category").Value,
                                        Memo = teamInfo.Attribute("Division").Value,
                                    };
//                                    context.Team.InsertOnSubmit(team);
  //                                  team.Contest = contest;
                                    if (teamInfo.Attribute("Exhibition") != null)
                                    {
                                        team.Memo += ";Exhibition=" + teamInfo.Attribute("Exhibition").Value;
                                    }
                                    context.AddToTeamSet(team);
                                    context.SaveChanges();
//                                    context.SubmitChanges();
                                }
                            }
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        public bool GetTurnInfoOfTeam(int gameId, string teamExId, long teamRegId, int roundNo, out int entryTeamId, out int turnNo, out CourseName course)
        {
            entryTeamId = -1;
            turnNo = 0;
            course = CourseName.IN;

            using (ETRCGoVADBEntities context = new ETRCGoVADBEntities())
            {
                var games = from g in context.GameSet
                            where g.GameId == gameId
                            select g;
                if (games.Count() > 0)
                {
                //    int regId = int.Parse(teamExId);
                    long regId = teamRegId;
                    var eteams = from et in games.First().EntryTeamSet
                                 where et.TeamSet.RegId == regId
                                 select et;
                    if (eteams.Count() > 0)
                    {
                        var eteam = eteams.First();
                        var turns = from t in eteam.TurnSet
                                    where t.RoundSet.RoundNo == roundNo
                                    select t;
                        if (turns.Count() > 0)
                        {
                            entryTeamId = eteam.EntryTeamId;
                            turnNo = turns.First().TurnNo;
                            course = CourseName.IN;
                            return true;
                        }
                        else
                        {
                            var turn1s = from t in eteam.TurnSet1
                                         where t.RoundSet.RoundNo == roundNo
                                         select t;
                            if (turn1s.Count() > 0)
                            {
                                entryTeamId = eteam.EntryTeamId;
                                turnNo = turn1s.First().TurnNo;
                                course = CourseName.OUT;
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }

        #endregion

        #region IETRoboConRaceMgmt Members


        public bool LoadContestInfo(string definition)
        {
            XmlReader reader = XmlReader.Create(new StringReader(definition));
            XDocument xdoc = XDocument.Load(reader);
            var govaRoot = xdoc.Element("GoVA");
            if (govaRoot == null)
            {
                return false;
            }
            using (ETRCGoVADBEntities db = new ETRCGoVADBEntities())
            {
                bool result = true;
                var tryBSs = new List<string>();
                var contests = from c in govaRoot.Elements("Contests").First().Elements("Contest")
                               select c;
                foreach (var contest in contests)
                {
                    string contestName = contest.Attribute("Name").Value;
                    var dbContests = from c in db.ContestSet
                                     where c.Name.CompareTo(contestName) == 0
                                     select c;
                    ContestSet dbContest = null;
                    if (dbContests.Count() == 0)
                    {
                        dbContest = new ContestSet { Name = contest.Attribute("Name").Value, Year = int.Parse(contest.Attribute("Year").Value) };
                        db.AddToContestSet(dbContest);
                        db.SaveChanges();
                        result = true;
                    }
                    else
                    {
                        dbContest = dbContests.First();
                        dbContest.Year = int.Parse(contest.Attribute("Year").Value);
                        db.SaveChanges();
                    }
                    var tryAreas = new List<string>();
                    var areas = from a in contest.Elements("Areas").First().Elements("Area")
                                select a;
                    foreach (var area in areas)
                    {
                        var dbAreas = from a in dbContest.AreaSet
                                      where a.Name.CompareTo(area.Attribute("Name").Value) == 0 && a.Contest_ContestId == dbContest.ContestId
                                      select a;
                        tryAreas.Add(area.Attribute("Name").Value);
                        if (dbAreas.Count() == 0)
                        {
                            var dbArea = new AreaSet { Name = area.Attribute("Name").Value, ContestSet = dbContest };
                            db.AddToAreaSet(dbArea);
                            db.SaveChanges();
                        }
                        else
                        {

                        }
                    }
                    var registedAreas = from a in dbContest.AreaSet select a;
                    foreach (var ra in registedAreas)
                    {
                        bool found = false;
                        foreach (var area in tryAreas)
                        {
                            if (area.CompareTo(ra.Name) == 0)
                            {
                                tryAreas.Remove(area);
                                found = true;
                                break;
                            }
                        }
                        if (!found)
                        {
                            db.DeleteObject(ra);
                        }
                    }
                    db.SaveChanges();
                }
                var gameSpecs = from gs in govaRoot.Elements("GameSpecs").First().Elements("GameSpec") select gs;
                foreach (var gameSpec in gameSpecs)
                {
                    string gameSpecName = gameSpec.Attribute("Name").Value;
                    var dbGameSpecs = from gs in db.GameSpecSet
                                      where gs.Name.CompareTo(gameSpecName) == 0
                                      select gs;
                    GameSpecSet dbGameSpec = null;
                    if (dbGameSpecs.Count() == 0)
                    {
                        dbGameSpec = new GameSpecSet { Name = gameSpec.Attribute("Name").Value };
                        db.AddToGameSpecSet(dbGameSpec);
                        db.SaveChanges();
                    }
                    else
                    {
                        dbGameSpec = dbGameSpecs.First();
                        List<GameCourseSpecSet> deletingGCS = new List<GameCourseSpecSet>();
                        foreach (var gcs in dbGameSpec.GameCourseSpecSet)
                        {
                            deletingGCS.Add(gcs);
                        }
                        foreach (var gcs in deletingGCS)
                        {
                            List<BonusSpecSet> deletingBS = new List<BonusSpecSet>();
                            foreach (var bs in gcs.BonusSpecSet)
                            {
                                deletingBS.Add(bs);
                            }
                            foreach (var dbs in deletingBS)
                            {
                                db.DeleteObject(dbs);
                            }
                            db.DeleteObject(gcs);
                            db.SaveChanges();
                        }
                    }
                    var gameCourseSpecs = from gcs in gameSpec.Elements("GameCourseSpecs").First().Elements("GameCourseSpec") select gcs;
                    foreach (var gameCourseSpec in gameCourseSpecs)
                    {
                        var dbGameCourseSpec = new GameCourseSpecSet { CourseName = gameCourseSpec.Attribute("CourseName").Value, GameSpecSet = dbGameSpec };
                        db.AddToGameCourseSpecSet(dbGameCourseSpec);
                        db.SaveChanges();
                        int order=0;
                        var bonusSpecs = from bs in gameCourseSpec.Elements("BonusSpecs").First().Elements("BonusSpec") select bs;
                        foreach (var bonusSpec in bonusSpecs)
                        {
                            var dbBonusSpec = new BonusSpecSet
                            {
                                Name = bonusSpec.Attribute("Name").Value,
                                ShortName = bonusSpec.Attribute("ShortName").Value,
                                GameCourseSpecSet= dbGameCourseSpec,
                                Point = int.Parse(bonusSpec.Attribute("Point").Value),
                                ClearOrder = order++
                            };
                            db.AddToBonusSpecSet(dbBonusSpec);
                            db.SaveChanges();
                        }
                    }
                }
                return result;
            }
        }

        #endregion

        #region IETRoboConRaceMgmt Members

        public bool ClearEntryTeamModelPoint(int gameId)
        {
            bool result = false;
            using (var db = new ETRCGoVADBEntities())
            {
                var entryTeams = from et in db.EntryTeamSet
                                 where et.Game_GameId == gameId
                                 select et;
                var ets = new List<EntryTeamSet>();
                foreach (var et in entryTeams)
                {
                    ets.Add(et);
                }

                foreach (var et in ets)
                {
                    et.ModelTotalPoint = null;
                }
                db.SaveChanges();
            }
            return result;
        }
        public bool UpdateEntryTeamModelPoint(int entryTeamId, int modelPoint)
        {
            using (var db = new ETRCGoVADBEntities())
            {
                var entryTeams = from et in db.EntryTeamSet
                                 where et.TeamSet.RegId == entryTeamId
                                 select et;
                if (entryTeams.Count() > 0)
                {
                    var entryTeam = entryTeams.First();
                    entryTeam.ModelTotalPoint = modelPoint;
                    db.SaveChanges();
                    return true;
                }
            }
            return false;
        }

        #endregion

        #region IETRoboConRaceMgmt Members


        public bool MoveCurrentTurnToFollow(int roundId, bool isLast)
        {
            using (var db = new ETRCGoVADBEntities())
            {
                var races = from r in db.RaceSet
                            where r.TurnSet.Round_RoundId == roundId
                            orderby r.TurnOrder
                            select r;
                if (races.Count() == 0)
                {
                    return false;
                }
                var raceList = new List<RaceSet>();
                if (races.Count() > 0)
                {
                    foreach (var r in races)
                    {
                        raceList.Add(r);
                    }
                }
                if (raceList.Count>1)
                {
                    var nextRace = raceList[0];
                    if (isLast)
                    {
                        nextRace.TurnOrder = raceList.Last().TurnOrder + 1;
                    }
                    else
                    {
                        int temp = nextRace.TurnOrder;
                        nextRace.TurnOrder = raceList[1].TurnOrder;
                        raceList[1].TurnOrder = temp;
                    }
                    db.SaveChanges();
                }
                return true;
            }
        }

        #endregion

        #region IETRoboConRaceMgmt Members


        public bool GetTeamTotalResults(int gameId, out TeamTotalResult[] results)
        {
            var points = new List<TeamTotalResult>();
            using (ETRCGoVADBEntities db = new ETRCGoVADBEntities())
            {
                var nrp = new Dictionary<int, double>();
                var nmp = new Dictionary<int, double>();
                CaliculateRaceOrder(gameId, out nrp, out nmp);
                var ets = from et in db.EntryTeamSet
                          where et.Game_GameId == gameId
                          orderby et.Bib
                          select et;

                if (ets.Count() > 0)
                {
                    foreach (var et in ets)
                    {
                        var ttr =
                            new TeamTotalResult
                            {
                                TeamId = et.Team_TeamId,
                                Bib = et.Bib,
                                Name = et.TeamSet.Name
                            };
                        if (et.Rank != null)
                        {
                            ttr.Rank = et.Rank.Value;
                        }
                        if (nrp.ContainsKey(et.EntryTeamId))
                        {
                            ttr.NormalizedResultPoints = nrp[et.EntryTeamId];
                        }
                        if (nmp.ContainsKey(et.EntryTeamId))
                        {
                            ttr.NormalizedModelPoint = nmp[et.EntryTeamId];
                        }

                        foreach (var tr in et.TurnRunnerSet)
                        {
                            if (tr.GameCourseSpecSet.CourseName.CompareTo("IN") == 0)
                            {
                                ttr.InCourseResult = tr.Status;
                            }
                            else
                            {
                                ttr.OutCourseResult = tr.Status;
                            }
                        }
                        points.Add(ttr);
                    }
                    results = points.ToArray();
                    return true;
                }
            }
            results = points.ToArray();
            return false;
        }

        #endregion
    }
}
